package com.chacha.framework.dasboard.tools;

/**
 * 
 */

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

/**
 * @author rachmat_doni@smltech.co.id
 * 
 */

public class DataJsonMultiStackSeries {

	private List<String> properties;
	private List<String> categorys;
	private List<DataSet> datasets;
	private List<TrendLine> trendLines;
	private List<VLine> vLines;
	private LineSet lineSet;

	public DataJsonMultiStackSeries(List<String> properties) {
		this.properties = properties;
		categorys = new ArrayList<String>();
		datasets = new ArrayList<DataSet>();
		trendLines = new ArrayList<>();
		vLines = new ArrayList<>();
	}

	public void addData(String label, String dataSetName, String seriesName,
			String color, String showValues, String value, String url) {
		boolean existDataset = false, existData = false;
		// create category
		for (String ctg : categorys) {
			if (ctg.equalsIgnoreCase(label)) {
				existDataset = true;
			}
		}
		if (!existDataset) {
			categorys.add(label);
		}

		// create dataset
		existDataset = false;
		for (DataSet set : datasets) {
			if (set.getName().equalsIgnoreCase(dataSetName)) {
				for (Data data : set.getData())
					if (data.getSeriesName().equalsIgnoreCase(seriesName)) {
						data.getValue().add(value);
						data.getLink().add(url);
						existData = true;
					}
				if (!existData) {
					Data data = new Data(seriesName, color, showValues,
							new ArrayList<String>(), new ArrayList<String>(),
							new ArrayList<String>());
					data.getValue().add(value);
					data.getLink().add(url);
					set.getData().add(data);
				}
				existDataset = true;
			}
		}

		if (!existDataset) {
			DataSet dataSet = new DataSet(dataSetName);
			Data data = new Data(seriesName, color, showValues,
					new ArrayList<String>(), new ArrayList<String>(),
					new ArrayList<String>());
			data.getValue().add(value);
			data.getLink().add(url);
			dataSet.getData().add(data);
			datasets.add(dataSet);
		}

	}

	public void addVLine(int insert, List<String> props) {
		vLines.add(new VLine(insert, props));
	}

	public void addBaseLine(List<String> properties) {
		boolean isExist = false;
		for (String prop : properties) {
			for (TrendLine line : trendLines) {
				for (String prop1 : line.getProperties()) {
					if (StringUtils.containsIgnoreCase(prop1, "displayvalue")
							&& prop1.equalsIgnoreCase(prop)) {
						isExist = true;
					}
				}
			}
		}
		if (!isExist)
			trendLines.add(new TrendLine(properties));
	}
	
	public void addLineSet(List<String> properties, List<String> values) {
		lineSet = new LineSet(properties, values);
	}

	public String getJSONData() {
		StringBuilder initBuil = new StringBuilder("{   \"chart\": {");
		StringBuilder trendlineBuil = new StringBuilder(",\"trendlines\":[");
		StringBuilder categoryBuil = new StringBuilder(
				"\"categories\":[{\"category\":[");
		StringBuilder datasetBuil = new StringBuilder("\"dataset\":[");

		for (String prop : properties) {
			initBuil.append(prop + ", ");
		}
		initBuil.delete(initBuil.length() - 2, initBuil.length());
		initBuil.append("}, ");

		int count = 0;
		for (String label : categorys) {
			categoryBuil.append("{ \"label\": \"" + label + "\" },");

			if (vLines.size() > 0) {
				for (VLine line : vLines) {
					if (line.getInsert() == count) {
						categoryBuil.append("{ \"vline\":\"true\", ");
						for (String val : line.getProperties()) {
							categoryBuil.append(val + ",");
						}
						categoryBuil.delete(categoryBuil.length() - 1,
								categoryBuil.length());
						categoryBuil.append(" },");
					}
				}
				count++;
			}
		}
		categoryBuil.delete(categoryBuil.length() - 1, categoryBuil.length());
		categoryBuil.append("]} ],");

		for (DataSet dataSet : datasets) {
			datasetBuil.append("{\"dataset\":[");
			for (Data data : dataSet.getData()) {
				datasetBuil.append("{ \"seriesname\":\"" + data.getSeriesName()
						+ "\", ");

				if (data.getColor() != null) {
					datasetBuil.append("\"color\": \"" + data.getColor()
							+ "\", ");
				}
				if (data.getShowValues() != null) {
					datasetBuil.append("\"showvalues\": \""
							+ data.getShowValues() + "\", ");
				}

				datasetBuil.append("\"data\":[");

				for (int i = 0; i < data.getValue().size(); i++) {
					datasetBuil.append("{ \"value\": \""
							+ data.getValue().get(i) + "\" ");
					if (data.getLink().get(i) != null
							&& !data.getLink().get(i).isEmpty())
						datasetBuil.append(",\"link\": \""
								+ data.getLink().get(i) + "\"");

					datasetBuil.append("},");
				}
				datasetBuil.delete(datasetBuil.length() - 1,
						datasetBuil.length());
				datasetBuil.append("]},");
			}
			datasetBuil.delete(datasetBuil.length() - 1, datasetBuil.length());
			datasetBuil.append("]},");
		}
		datasetBuil.delete(datasetBuil.length() - 1, datasetBuil.length());
		datasetBuil.append("]");

		if (trendLines.size() > 0) {
			trendlineBuil.append("{ \"line\":[");
			for (TrendLine line : trendLines) {
				trendlineBuil.append("{ ");
				for (String prop : line.getProperties()) {
					trendlineBuil.append(prop + ",");
				}
				trendlineBuil.delete(trendlineBuil.length() - 1,
						trendlineBuil.length());
				trendlineBuil.append(" },");
			}
			trendlineBuil.delete(trendlineBuil.length() - 1,
					trendlineBuil.length());
			trendlineBuil.append("]}]");
		} else
			trendlineBuil = new StringBuilder();

		if(categorys.size()>0){
			initBuil.append(categoryBuil.toString());
			initBuil.append(datasetBuil.toString());
		}else{
			initBuil.delete(initBuil.length()-2, initBuil.length());
		}
		
		initBuil.append(trendlineBuil.toString() + "}");

		return initBuil.toString();
	}

	// Try multiple [S]
	public String getJSONDataMultiple() {
//		DecimalFormat df = new DecimalFormat("####.##");
		StringBuilder initBuil = new StringBuilder("{   \"chart\": {");
		StringBuilder trendlineBuil = new StringBuilder(",\"trendlines\":[");
		StringBuilder categoryBuil = new StringBuilder(
				"\"categories\":[{\"category\":[");
		StringBuilder datasetBuil = new StringBuilder("\"dataset\":[");
		
		StringBuilder linesetBuil = new StringBuilder("");

		for (String prop : properties) {
			initBuil.append(prop + ", ");
		}
		initBuil.delete(initBuil.length() - 2, initBuil.length());
		initBuil.append("}, ");

		int count = 0;
		for (String label : categorys) {
			categoryBuil.append("{ \"label\": \"" + label + "\" },");

			if (vLines.size() > 0) {
				for (VLine line : vLines) {
					if (line.getInsert() == count) {
						categoryBuil.append("{ \"vline\":\"true\", ");
						for (String val : line.getProperties()) {
							categoryBuil.append(val + ",");
						}
						categoryBuil.delete(categoryBuil.length() - 1,
								categoryBuil.length());
						categoryBuil.append(" },");
					}
				}
				count++;
			}
		}
		categoryBuil.delete(categoryBuil.length() - 1, categoryBuil.length());
		categoryBuil.append("]} ],");

		for (DataSet dataSet : datasets) {
			datasetBuil.append("{\"dataset\":[");
			for (Data data : dataSet.getData()) {
				datasetBuil.append("{ \"seriesname\":\"" + data.getSeriesName()
						+ "\", ");

				if (data.getColor() != null) {
					datasetBuil.append("\"color\": \"" + data.getColor()
							+ "\", ");
				}
				if (data.getShowValues() != null) {
					datasetBuil.append("\"showvalues\": \""
							+ data.getShowValues() + "\", ");
				}

				datasetBuil.append("\"data\":[");

				for (int i = 0; i < data.getValue().size(); i++) {
					datasetBuil.append("{ \"value\": \""
							+ data.getValue().get(i) + "\" ");
					if (data.getLink().get(i) != null
							&& !data.getLink().get(i).isEmpty())
						datasetBuil.append(",\"link\": \""
								+ data.getLink().get(i) + "\"");

					datasetBuil.append("},");
				}
				datasetBuil.delete(datasetBuil.length() - 1,
						datasetBuil.length());
				datasetBuil.append("]},");
			}
			datasetBuil.delete(datasetBuil.length() - 1, datasetBuil.length());
			datasetBuil.append("]},");
		}
		datasetBuil.delete(datasetBuil.length() - 1, datasetBuil.length());
		datasetBuil.append("]");

		if (trendLines.size() > 0) {
			trendlineBuil.append("{ \"line\":[");
			for (TrendLine line : trendLines) {
				trendlineBuil.append("{ ");
				for (String prop : line.getProperties()) {
					trendlineBuil.append(prop + ",");
				}
				trendlineBuil.delete(trendlineBuil.length() - 1,
						trendlineBuil.length());
				trendlineBuil.append(" },");
			}
			trendlineBuil.delete(trendlineBuil.length() - 1,
					trendlineBuil.length());
			trendlineBuil.append("]}]");
		} else
			trendlineBuil = new StringBuilder();
		
		if(lineSet!=null){
			linesetBuil.append("\"lineset\": {");
			for(String prop: lineSet.getProperties()){
				linesetBuil.append(prop+",");
			}
			
			linesetBuil.append("\"data\":[");
			for(String val: lineSet.getValues()){
				linesetBuil.append("{ \"value\":\"" + val+ "\"},");
			}
			linesetBuil.delete(linesetBuil.length()-1, linesetBuil.length());
			linesetBuil.append("]");
			linesetBuil.append("}");
			
		}
		
		if(categorys.size()>0 ){
			initBuil.append(categoryBuil.toString());
			initBuil.append(datasetBuil.toString());
			if(linesetBuil.length()>0)initBuil.append(","+linesetBuil.toString());
			initBuil.append(trendlineBuil.toString());
			//initBuil.delete(initBuil.length()-1, initBuil.length());
		}else{
			initBuil.delete(initBuil.length()-2, initBuil.length());
		}
		initBuil.append("}");
		
		return initBuil.toString();
	}

	public void addDataMultiple(String label, String dataSetName,
			String seriesName, String color, String showValues, String value,
			String toolText, String url) {
		boolean existDataset = false, existData = false;
		// create category
		for (String ctg : categorys) {
			if (ctg.equalsIgnoreCase(label)) {
				existDataset = true;
			}
		}
		if (!existDataset) {
			categorys.add(label);
		}

		// create dataset
		existDataset = false;
		for (DataSet set : datasets) {
			if (set.getName().equalsIgnoreCase(dataSetName)) {
				for (Data data : set.getData())
					if (data.getSeriesName().equalsIgnoreCase(seriesName)) {
						data.getValue().add(value);
						data.getToolText().add(toolText);
						data.getLink().add(url);
						existData = true;
					}
				if (!existData) {
					Data data = new Data(seriesName, color, showValues,
							new ArrayList<String>(), new ArrayList<String>(),
							new ArrayList<String>());
					data.getValue().add(value);
					data.getToolText().add(toolText);
					data.getLink().add(url);
					set.getData().add(data);
				}
				existDataset = true;
			}
		}

		if (!existDataset) {
			DataSet dataSet = new DataSet(dataSetName);
			Data data = new Data(seriesName, color, showValues,
					new ArrayList<String>(), new ArrayList<String>(),
					new ArrayList<String>());
			data.getValue().add(value);
			data.getToolText().add(toolText);
			data.getLink().add(url);
			dataSet.getData().add(data);
			datasets.add(dataSet);
		}
	}

	// Try multiple [E]

	private class DataSet {
		private String name;
		private List<Data> data;

		public DataSet(String name) {
			this.name = name;
			this.data = new ArrayList<>();
		}

		public String getName() {
			return name;
		}

		public List<Data> getData() {
			return data;
		}

	}

	private class Data {
		/**
		 * 
		 */
		private String seriesName;
		private String color;
		private String showValues;
		private List<String> value;
		private List<String> link;
		private List<String> toolText;

		public Data(String seriesName, String color, String showValues,
				List<String> value, List<String> link, List<String> toolText) {
			super();
			this.color = color;
			this.showValues = showValues;
			this.seriesName = seriesName;
			this.value = value;
			this.link = link;
			this.toolText = toolText;
		}

		public String getShowValues() {
			return showValues;
		}

		public String getColor() {
			return color;
		}

		public List<String> getValue() {
			return value;
		}

		public List<String> getLink() {
			return link;
		}

		public String getSeriesName() {
			return seriesName;
		}

		public List<String> getToolText() {
			return toolText;
		}
	}

	private class TrendLine {
		private List<String> properties;

		public TrendLine(List<String> properties) {
			super();
			this.properties = properties;
		}

		public List<String> getProperties() {
			return properties;
		}
	}

	private class VLine {
		private int insert;
		private List<String> properties;

		public VLine(int insert, List<String> properties) {
			super();
			this.insert = insert;
			this.properties = properties;
		}

		public int getInsert() {
			return insert;
		}

		public List<String> getProperties() {
			return properties;
		}
	}
	
	private class LineSet {
		private List<String> values;
		private List<String> properties;

		public LineSet(List<String> properties, List<String> values) {
			super();
			this.properties=properties;
			this.values = values;
		}

		public List<String> getValues() {
			return values;
		}

		public List<String> getProperties() {
			return properties;
		}

	

		
		
	}
}